#include <iostream>
#include <string>
#include "Any.hpp"
#include <map>
// 用于测试的简单类
class TestClass
{
public:
    TestClass(int val = 0) : value(val)
    {
        std::cout << "TestClass 构造函数被调用" << std::endl;
    }
    int getValue() const { return value; }

private:
    int value;
};

struct Configuration
{
    std::map<std::string, Any> settings;

    void setSetting(const std::string &key, const Any &value)
    {
        settings[key] = value;
    }

    template <typename T>
    T getSetting(const std::string &key)
    {
        return settings[key].AnyCast<T>();
    }
};

// 测试用例集合
void run_any_tests()
{
    std::cout << "\n=== Any 类测试开始 ===\n"
              << std::endl;

    // 测试1：基本类型存储和检索
    {
        std::cout << "测试1：基本类型操作" << std::endl;
        Any intAny(42);
        std::cout << "创建了包含整数的 Any 对象" << std::endl;

        std::cout << "类型检查: " << (intAny.Is<int>() ? "是整数" : "不是整数") << std::endl;
        std::cout << "值: " << intAny.AnyCast<int>() << std::endl;

        // 测试错误的类型转换
        std::cout << "尝试错误的类型转换..." << std::endl;
        try
        {
            intAny.AnyCast<std::string>();
        }
        catch (const std::bad_cast &)
        {
            std::cout << "捕获到预期的类型转换异常" << std::endl;
        }
    }

    // 测试2：字符串类型操作
    {
        std::cout << "\n测试2：字符串类型操作" << std::endl;
        Any strAny(std::string("Hello, Any!"));
        std::cout << "创建了包含字符串的 Any 对象" << std::endl;

        std::cout << "类型检查: " << (strAny.Is<std::string>() ? "是字符串" : "不是字符串") << std::endl;
        std::cout << "值: " << strAny.AnyCast<std::string>() << std::endl;
    }

    // 测试3：自定义类型操作
    {
        std::cout << "\n测试3：自定义类型操作" << std::endl;
        Any customAny(TestClass(123));
        std::cout << "创建了包含自定义类型的 Any 对象" << std::endl;

        std::cout << "类型检查: " << (customAny.Is<TestClass>() ? "是TestClass" : "不是TestClass") << std::endl;
        std::cout << "值: " << customAny.AnyCast<TestClass>().getValue() << std::endl;
    }

    // 测试4：拷贝和移动操作
    {
        std::cout << "\n测试4：拷贝和移动操作" << std::endl;
        Any original(100);
        std::cout << "创建原始 Any 对象" << std::endl;

        // 测试拷贝
        Any copied = original;
        std::cout << "拷贝后的值: " << copied.AnyCast<int>() << std::endl;

        // 测试移动
        Any moved = std::move(copied);
        std::cout << "移动后的值: " << moved.AnyCast<int>() << std::endl;
    }

    // 测试5：空Any对象操作
    {
        std::cout << "\n测试5：空Any对象操作" << std::endl;
        Any empty;
        std::cout << "创建空的 Any 对象" << std::endl;
        std::cout << "IsNull检查: " << (empty.IsNull() ? "是空的" : "不是空的") << std::endl;
    }

    // 测试6：实际应用场景 - 配置系统
    {
        std::cout << "\n测试6：模拟配置系统" << std::endl;
        // 使用 Any 存储不同类型的配置项
        Any windowWidth(1920);
        Any windowHeight(1080);
        Any windowTitle(std::string("My Application"));
        Any isFullscreen(true);
        Any backgroundColor(std::string("#FFFFFF"));

        std::cout << "配置信息："
                  << "\n窗口宽度: " << windowWidth.AnyCast<int>()
                  << "\n窗口高度: " << windowHeight.AnyCast<int>()
                  << "\n窗口标题: " << windowTitle.AnyCast<std::string>()
                  << "\n全屏模式: " << (isFullscreen.AnyCast<bool>() ? "是" : "否")
                  << "\n背景颜色: " << backgroundColor.AnyCast<std::string>()
                  << std::endl;
    }

    // 测试7：实际应用场景 - 消息传递系统
    {
        std::cout << "\n测试7：模拟消息传递系统" << std::endl;

        // 定义不同类型的消息内容
        struct UserMessage
        {
            std::string content;
            UserMessage(const std::string &c) : content(c) {}
        };

        // 模拟不同类型的消息
        Any textMessage(std::string("普通文本消息"));
        Any numberMessage(42); // 数字类型消息
        Any customMessage(UserMessage("自定义消息类型"));

        // 模拟消息处理
        std::cout << "处理不同类型的消息：" << std::endl;
        if (textMessage.Is<std::string>())
        {
            std::cout << "文本消息: " << textMessage.AnyCast<std::string>() << std::endl;
        }
        if (numberMessage.Is<int>())
        {
            std::cout << "数字消息: " << numberMessage.AnyCast<int>() << std::endl;
        }
        if (customMessage.Is<UserMessage>())
        {
            std::cout << "自定义消息: " << customMessage.AnyCast<UserMessage>().content << std::endl;
        }
    }

    // 测试8：实际应用场景 - 插件系统
    {
        std::cout << "\n测试8：模拟插件系统" << std::endl;

        // 模拟插件返回的不同类型数据
        class Plugin
        {
        public:
            Any ProcessData(const std::string &type)
            {
                if (type == "int")
                    return Any(42);
                if (type == "string")
                    return Any(std::string("插件处理结果"));
                if (type == "custom")
                    return Any(TestClass(999));
                return Any();
            }
        };

        Plugin plugin;
        std::cout << "插件处理不同类型的数据：" << std::endl;

        Any result1 = plugin.ProcessData("int");
        Any result2 = plugin.ProcessData("string");
        Any result3 = plugin.ProcessData("custom");

        std::cout << "整数结果: " << result1.AnyCast<int>() << std::endl;
        std::cout << "字符串结果: " << result2.AnyCast<std::string>() << std::endl;
        std::cout << "自定义类型结果: " << result3.AnyCast<TestClass>().getValue() << std::endl;
    }

    // ... existing code ...

    // 测试9：开源项目应用实例
    {
        std::cout << "\n测试9：开源项目应用实例" << std::endl;

        // 1. Boost.Any 的应用示例 (Boost库)
        std::cout << "\n示例1：类似于Boost.Any的属性系统" << std::endl;
        // Boost库中使用Any来实现属性系统，允许对象携带任意类型的属性
        {
            Any properties[3];
            properties[0] = std::string("property1"); // 字符串属性
            properties[1] = 42;                       // 整数属性
            properties[2] = 3.14;                     // 浮点数属性

            std::cout << "属性1(string): " << properties[0].AnyCast<std::string>() << std::endl;
            std::cout << "属性2(int): " << properties[1].AnyCast<int>() << std::endl;
            std::cout << "属性3(double): " << properties[2].AnyCast<double>() << std::endl;
        }

        // 2. Qt的QVariant使用场景 (Qt框架)
        std::cout << "\n示例2：类似于Qt的QVariant应用" << std::endl;
        // Qt中使用QVariant存储界面组件的属性
        {
            struct Widget
            {
                Any property;
                void setProperty(const Any &value) { property = value; }
                Any getProperty() const { return property; }
            };

            Widget button;
            button.setProperty(std::string("Button1")); // 设置按钮名称
            std::cout << "按钮名称: " << button.getProperty().AnyCast<std::string>() << std::endl;
        }

        // 3. POCO库中的Variant使用场景
        std::cout << "\n示例3：类似于POCO的动态配置" << std::endl;
        // POCO库使用Variant实现动态配置系统
        {

            Configuration config;
            config.setSetting("port", 8080);
            config.setSetting("host", std::string("localhost"));
            config.setSetting("timeout", 30.5);

            std::cout << "服务器配置："
                      << "\n端口: " << config.getSetting<int>("port")
                      << "\n主机: " << config.getSetting<std::string>("host")
                      << "\n超时: " << config.getSetting<double>("timeout")
                      << std::endl;
        }

        // 4. Apache Thrift的Variant使用场景
        std::cout << "\n示例4：类似于Thrift的数据序列化" << std::endl;
        // Thrift使用Variant处理跨语言数据传输
        {
            struct ThriftMessage
            {
                std::string type;
                Any data;
            };

            ThriftMessage msg;
            msg.type = "UserProfile";
            // 模拟序列化的用户数据
            struct UserProfile
            {
                std::string name;
                int age;
                UserProfile(const std::string &n, int a) : name(n), age(a) {}
            };
            msg.data = UserProfile("张三", 25);

            if (msg.type == "UserProfile")
            {
                auto profile = msg.data.AnyCast<UserProfile>();
                std::cout << "用户信息 - 姓名: " << profile.name
                          << ", 年龄: " << profile.age << std::endl;
            }
        }
    }

    std::cout << "\n=== Any 类测试结束 ===\n"
              << std::endl;
}

int main()
{
    run_any_tests();
    return 0;
}